﻿using System;
using System.IO;
using System.Linq;
using BLL.Utils;
using DAL.Clipboard;
using DAL.File;
using DAL.Process;
using FileAccess = DAL.File.FileAccess;

namespace BLL.Model
{
    public class ClipboardSyncManager
    {
        protected IClipboardAccess ClipboardAccess = new ClipboardAccess();
        protected IFileAccess Fs = new FileAccess();
        protected IProcessAccess ProcessAccess = new ProcessAccess();

        public ClipboardSyncManager(IClipboardHistoryManager chMan, ProfileManager profileManager)
        {
            NextCallDoesntMatter = false;

            ChMan = chMan;
            ProfileManager = profileManager;

            ChMan.OnSelectedClipboardChanged += selectedClipboard =>
            {
                NextCallDoesntMatter = true;
                ClipboardAccess.SetClipboardContent(selectedClipboard);
            };

            Fs.FileChangedEvent += (sender, e) => ChMan.ClipboardChangeAction(() =>
            {
                // Only process files
                if (Directory.Exists(e.Filepath))
                    return;

                var parentPath = Path.GetDirectoryName(e.Filepath) + "\\";
                var newer = ProfileManager.LoadContent(parentPath);
                if (newer == null)
                    return;

                var older = ChMan.ClipboardHistory.FirstOrDefault(x => x.Path == parentPath);

                // Brand new element
                if (older == null)
                    ChMan.AddNewItem(newer);
                else // An element exists with the same path, refresh this element
                    older.Merge(newer);

                OnClipboardChanged.SafeInvoke();
            });

            ClipboardAccess.ClipboardChanged += delegate
            {
                var programName = (ProcessAccess.GetActiveProcessTitle() ?? "unknown") + " (" + (ProcessAccess.GetActiveProcessName() ?? "unknown") + ")";
                if (ProfileManager.Profile.IsAllowed(programName))
                    CreateNewSnapshot();
            };
        }

        public bool NextCallDoesntMatter { get; private set; }

        public IClipboardHistoryManager ChMan { get; private set; }
        public ProfileManager ProfileManager { get; private set; }
        public event Action OnClipboardChanged;

        public void EnableEvents()
        {
            Fs.SetFolderWatcher(Fs.SharedRoot);
            ClipboardAccess.RaiseChangeEvents = true;
        }

        public void CreateNewSnapshot()
        {
            if (NextCallDoesntMatter)
            {
                NextCallDoesntMatter = false;
                return;
            }

            var content = ClipboardAccess.GetClipboardContent();
            if (content == null)
                return;

            ProfileManager.SaveContent(content);

            ChMan.AddNewItem(content);
        }

        public void ClearClipboard()
        {
            ClipboardAccess.ClearClipboard();
        }

        public void LoadProfileContents()
        {
            ChMan.ClipboardHistory.Clear();
            foreach (var content in ProfileManager.LoadOldContents(25))
                ChMan.ClipboardHistory.Add(content);
        }
    }
}